package com.hgx.util;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.persistence.entity.GroupEntity;
import org.activiti.engine.impl.persistence.entity.UserEntity;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;

import com.google.gson.Gson;

public class ProcessBaseUtil {
	private ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("applicationContext.xml").buildProcessEngine();

	/**
	 * 流程部署
	 * 
	 * @param name
	 * @param processRecourcePath
	 * @return
	 */
	public Deployment processDefinition(String name, String processRecourcePath) {
		RepositoryService repositoryService = processEngine.getRepositoryService();
		Deployment deployment = repositoryService.createDeployment().name(name).addClasspathResource(processRecourcePath).deploy();
		return deployment;
	}

	/**
	 * 
	 * 流程提交(启动流程)
	 * 
	 * @param processKey
	 *            流程key
	 * 
	 * @param variables
	 *            流程变量
	 */
	public ProcessInstance startProcessInstance(String processKey, Map<String, Object> variables) {
		RuntimeService runtimeService = processEngine.getRuntimeService();
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processKey, variables);
		return processInstance;

	}

	/**
	 * 根据流程实例id和处理人查询当前任务
	 * 
	 * @param processInstanceId
	 * @param processAssignee
	 */
	public List<Task> findUserTaskIdByPIIdAndAss(String processInstanceId, String processAssignee) {
		// 获取TaskService服务对象的实例
		TaskService taskService = processEngine.getTaskService();
		List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).taskAssignee(processAssignee).list();
		return tasks;
	}

	/**
	 * 根据流程实例id和角色用户查询任务
	 * 
	 * @param processInstanceId
	 * @param processAssignee
	 */
	public List<Task> findUserTaskIdByPIIdAndTaskCandidateUser(String processInstanceId, String processAssignee) {
		// 获取TaskService服务对象的实例
		TaskService taskService = processEngine.getTaskService();
		List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).taskCandidateUser(processAssignee).list();
		return tasks;
	}

	/**
	 * 根据任务id完成任务
	 * 
	 * @param taskId
	 * @param variables
	 * @return
	 */
	public boolean userTaskCompleteByTaskId(String taskId, Map<String, Object> variables) {
		if (HStringUtil.isnull(taskId))
			return false;
		TaskService taskService = processEngine.getTaskService();
		if (HStringUtil.isnull(variables)) {
			taskService.complete(taskId);
		} else {
			taskService.complete(taskId, variables);
		}
		return true;
	}

	/**
	 * 某一次流程执行了多少步
	 * 
	 * @param processInstanceId
	 */
	public void queryHistoricActivitiInstance(String processInstanceId) {
		List<HistoricActivityInstance> list = processEngine.getHistoryService().createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).finished().list();
		if (list != null && list.size() > 0) {
			for (HistoricActivityInstance hai : list) {
				System.out.println(hai.getId());
				System.out.println("步骤ID：" + hai.getActivityId());
				System.out.println("步骤名称：" + hai.getActivityName());
				System.out.println("执行人：" + hai.getAssignee());
				System.out.println("====================================");
				System.out.println(new Gson().toJson(hai));
			}
		}
	}

	/**
	 * 创建默认角色
	 * 
	 * @return
	 */
	public boolean deploymentIdentity() {
		IdentityService identityService = processEngine.getIdentityService();
		// 添加角色
		identityService.saveGroup(new GroupEntity("M1"));
		identityService.saveGroup(new GroupEntity("M2"));
		// 添加用户
		identityService.saveUser(new UserEntity("胡一"));
		identityService.saveUser(new UserEntity("胡二"));
		identityService.saveUser(new UserEntity("胡三"));
		identityService.saveUser(new UserEntity("胡四"));
		identityService.saveUser(new UserEntity("胡五"));
		// 建立用户角色关系
		identityService.createMembership("胡一", "M1");
		identityService.createMembership("胡二", "M1");
		identityService.createMembership("胡三", "M1");
		identityService.createMembership("胡四", "M2");
		identityService.createMembership("胡五", "M1");
		return true;
	}

	/**
	 * 获取动态流程图
	 * 
	 * @param processInstanceId
	 * @param filePath
	 * @return
	 * @throws Exception
	 */
	public String dynamicProcessImg(String processInstanceId, String filePath) throws Exception {

		InputStream inputStream = dynamicProcessImg(processInstanceId);

		// 写入到磁盘
		byte[] data = new byte[1024];
		int len = 0;
		FileOutputStream fileOutputStream = null;
		String path = ((filePath.endsWith("/") || filePath.endsWith("\\")) ? filePath : filePath + "\\") + processInstanceId + ".png";
		fileOutputStream = new FileOutputStream(path);
		while ((len = inputStream.read(data)) != -1) {
			fileOutputStream.write(data, 0, len);
		}

		if (inputStream != null) {
			inputStream.close();
		}
		if (fileOutputStream != null) {
			fileOutputStream.close();
		}
		System.out.println("动态流程图 保存完成!");
		return path;
	}

	/**
	 * 获取动态流程图
	 * 
	 * @param processInstanceId
	 * @return
	 */
	public InputStream dynamicProcessImg(String processInstanceId) {
		RuntimeService runtimeService = processEngine.getRuntimeService();
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();

		RepositoryService repositoryService = processEngine.getRepositoryService();

		BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
		// 得到正在执行的环节
		List<String> activeIds = runtimeService.getActiveActivityIds(processInstance.getId());
		InputStream inputStream = new DefaultProcessDiagramGenerator().generateDiagram(bpmnModel, "png", activeIds, Collections.<String> emptyList(), processEngine.getProcessEngineConfiguration().getActivityFontName(), processEngine.getProcessEngineConfiguration().getLabelFontName(), null, 1.0);
//		InputStream inputStream = new DefaultProcessDiagramGenerator().generateDiagram(bpmnModel, "png", activeIds, Collections.<String> emptyList(), "宋体", "宋体", null, 1.0);
		return inputStream;
	}
}
